package ocmd

import (
	"fmt"
	"osiris/core/txpool"
	"osiris/dto"
	"osiris/errors"
	"osiris/logger"
	"sync"
)

// TxPoolHandler txpool命令handler
type TxPoolHandler struct{}

func (handler *TxPoolHandler) Handle(inputs []string, wg *sync.WaitGroup) error {
	defer wg.Done()

	if len(inputs) != 3 {
		return &errors.CommandInputError{
			Msg: "unknown command",
		}
	}

	switch inputs[1] {

	case LOCAL:

		switch inputs[2] {
		case QUEUED:
			printLocalQueuedTxs()
			return nil

		case PENDING:
			printLocalPendingTxs()
			return nil

		default:
			return &errors.CommandInputError{
				Msg: "unknown command",
			}
		}

	case REMOTE:

		switch inputs[2] {
		case QUEUED:
			printRemoteQueuedTxs()
			return nil

		case PENDING:
			printRemotePendingTxs()
			return nil

		default:
			return &errors.CommandInputError{
				Msg: "unknown command",
			}
		}

	default:
		return &errors.CommandInputError{
			Msg: "unknown command",
		}
	}
}

func printLocalQueuedTxs() {
	printQueued(txpool.GetLocalQueued())
}

func printLocalPendingTxs() {
	printPending(txpool.GetLocalPending())
}

func printRemoteQueuedTxs() {
	printQueued(txpool.GetRemoteQueued())
}

func printRemotePendingTxs() {
	printPending(txpool.GetRemotePending())
}

func printQueued(queued map[string]*txpool.TxDescendArray) {
	for addr, txs := range queued {
		logger.Printf("[addr %s]\n", addr)
		for index, tx := range txs.GetTxs() {
			logger.Printf("  %d. tx type: %d, nonce: %d, hash: %s\n", index+1, tx.TxType, tx.Nonce, tx.TxHash)
		}
	}
}

func printPending(pending map[string][]*dto.TxData) {
	for addr, txs := range pending {
		logger.Printf("[addr %s]\n", addr)
		for index, tx := range txs {
			logger.Printf("  %d. tx type: %d, nonce: %d, hash: %s\n", index+1, tx.TxType, tx.Nonce, tx.TxHash)
		}
	}
}

func (handler *TxPoolHandler) PrintHelp() {
	printCommand(fmt.Sprintf("%s %s %s", TXPOOL, LOCAL, QUEUED), "show all the txs in the local queued txpool")
	printCommand(fmt.Sprintf("%s %s %s", TXPOOL, LOCAL, PENDING), "show all the txs in the local pending txpool")
	printCommand(fmt.Sprintf("%s %s %s", TXPOOL, REMOTE, QUEUED), "show all the txs in the remote queued txpool")
	printCommand(fmt.Sprintf("%s %s %s", TXPOOL, REMOTE, PENDING), "show all the txs in the remote pending txpool")
}
